//
//  ZBFileManager.swift
//  ZBFileTool
//
//  Created by BO ZHOU on 2021/5/7.
//

import UIKit

public class ZBFileManager: NSObject {

    /**
     * 获取tmp文件夹路径
     */
    class func getTmpPath() -> String {
        return NSTemporaryDirectory()
    }
    
    /**
     * 获取doc文件夹路径
     */
    class func getDocPath() -> String {
        return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
    }
    
    /**
     * 判断路径是否为文件夹
     */
    class func isFolder(filePath: String) -> Bool {
        var isDirectory: ObjCBool = false
        FileManager.default.fileExists(atPath: filePath, isDirectory: &isDirectory)
        return isDirectory.boolValue
    }
    
    

    /**
     * 确保文件夹存在 (只能传入文件夹路径, 并非文件路径)
     */
    class func ensureFolderExistsWith(folderPath: String) {
    
        let isExists = FileManager.default.fileExists(atPath: folderPath)
        
        if !isExists {
            try? FileManager.default.createDirectory(atPath: folderPath, withIntermediateDirectories: true, attributes: nil)
        }
    }
    
    /**
     * 删除文件
     */
    class func removeFileWith(path: String) {
        try? FileManager.default.removeItem(atPath: path)
    }
    
    /**
     * 根据文件全路径获取文件所在的文件夹全路径
     */
    class func getFolderPathWith(filePath: String) -> String {
        return URL(fileURLWithPath: filePath).deletingLastPathComponent().path
    }
    
    /**
     * 根据文件全路径获取文件名
     */
    class func getFileNameWith(filePath: String) -> String {
        return URL(fileURLWithPath: filePath).lastPathComponent
    }
    
    /**
     * 移动文件路径
     */
    class func moveItem(fromPath: String, toPath: String) {
        try? FileManager.default.moveItem(atPath: fromPath, toPath: toPath)
    }
    
    /**
     * 拷贝文件
     */
    class func copyItem(atPath: String, toPath: String) {
        try? FileManager.default.copyItem(atPath: atPath, toPath: toPath)
    }
    
    /**
     * 遍历文件夹下面所有子路径 (深层遍历), 返回该文件夹下面的所有文件相对路径
     * - parameter atPath: 路径
     * - parameter isFileterDirectory: 是否过滤子文件夹 (如查询/Users下面的所有文件, /Users/Document/a.txt, 会过滤掉Document, 只返回a.txt, 否则会返回两个)
     * - parameter isFilterHideFiles: 是否过滤隐藏文件 (以.开头的文件名, 如.git, .DS_STORE等, 默认过滤)
     */
    class func files(atPath: String, isFileterDirectory: Bool = true, isFilterHideFiles: Bool = true) -> [String] {
        
        let directoryFiles = FileManager.default.enumerator(atPath: atPath)
                
        var filesArr = [String]()
        
        for name in directoryFiles?.allObjects as! [String] {
            
            
            let ns_name = name as NSString
            
            if isFilterHideFiles && ns_name.hasPrefix(".") {
                // 隐藏文件, 舍弃
            } else if (isFileterDirectory && isFolder(filePath: atPath + "/" + name)) {
                // 文件夹, 舍弃
            } else {
                filesArr.append(name)
            }
        }
        
        return filesArr
    }
    
//    
//    /**
//     * 按照既定规则复制文件到另一个目录下
//     */
//    class func copyFile(atPath: String, toPath: String, originRegularContent: String, toRegularContent: String) {
//        
//        
//        // 原文件全路径
//        let fromFileFullPath = atPath
//        let fromFileName = self.getFileNameWith(filePath: fromFileFullPath)
//        
//        
//        // 源文件内容
//        let fromFileContent = try? String(contentsOfFile: fromFileFullPath, encoding: .utf8)
//        
//        // 创建新的目标文件内容
//        let toFileContent = fromFileContent?.replacingOccurrences(of: originRegularContent, with: toRegularContent)
//        
//        // 创建写入的目标文件名 (名称可能会包含子路径, 并不是严格意义的文件名)
//        let toFileName = fromFileName.replacingOccurrences(of: originRegularContent, with: toRegularContent)
//        // 创建写入的目标文件全路径
//        let toFileFullPath = toPath + "/" + toFileName
//        
//        // 获取想要写入的文件夹路径
//        let toFileDir = ZBFileManager.getFolderPathWith(filePath: toFileFullPath)
//        // 确保这个路径存在
//        ZBFileManager.ensureFolderExistsWith(folderPath: toFileDir)
//        // 新内容写入
//        try? toFileContent?.write(toFile: toFileFullPath, atomically: true, encoding: .utf8)
//    }
    
}


extension String {
    
    func ensureWrite(toFile: String, atomically: Bool = true, encoding: Encoding = .utf8) {
        
        // 获取写入路径的foler路径
        let folderPath = ZBFileManager.getFolderPathWith(filePath: toFile)
        
        // 确保folder路径存在, 不存在就自动创建
        ZBFileManager.ensureFolderExistsWith(folderPath: folderPath)
        
        try? self.write(toFile: toFile, atomically: atomically, encoding: encoding)
    }
    
    
}


//运算符函数要声明在文件的最外层，不能在类里

//声明•的precedencegroup名：PointMultiplicationPrecedence
precedencegroup StringAppendingComponentPrecedence {
    associativity: left//左结合
    higherThan: AdditionPrecedence//优先级：比加法高
    lowerThan: MultiplicationPrecedence//优先级：比乘法低
}

infix operator /+/: StringAppendingComponentPrecedence

/// Point的数量积（Option+8）
///
/// - Parameters:
///   - left: One Point
///   - right: Other Point
/// - Returns: left + "/" + right
func /+/(leftString: String, rightString: String) -> String {
    return leftString + "/" + rightString
}
